package com.leon.androidui.customview;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;

import java.util.Arrays;

public class Practice11PieChartView extends View {

    int[] colors = {Color.parseColor("#f44236"), Color.parseColor("#fec107"), Color.parseColor("#972dad")
            , Color.parseColor("#9aa09f"), Color.parseColor("#029688"), Color.parseColor("#2196f3")};
    String[] labels = {"Lollipop", "Marshmallow", "Gingerbread", "Ice Cream Sandwich", "Jelly Bean", "Kitkat"};
    int[] angles = {108, 54, 18, 18, 54, 108};
    int[] startAngles;
    int[] endAngles;
    int startAngle = -180;
    RectF rect = new RectF(-200, -200, 200, 200);
    Paint paint = new Paint();

    int spaceAngle = 2;

    int translateRadius = 30;
    int radius = 200;
    int selectPosition = 5;

    Path leftTopLinePath = new Path();
    Paint pathPaint = new Paint();
    Paint lablePaint = new Paint();

    private float centerX = 0;
    private float centerY = 0;

    public Practice11PieChartView(Context context) {
        super(context);
    }

    public Practice11PieChartView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initView(context, attrs);
    }

    public Practice11PieChartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    private void initView(Context context, AttributeSet attrs) {
        startAngles = new int[angles.length];
        endAngles = new int[angles.length];
        int tempStartAngle = startAngle;
        for (int i = 0; i < angles.length; i++) {
            startAngles[i] = tempStartAngle;
            endAngles[i] = tempStartAngle + angles[i];
            tempStartAngle = endAngles[i];
        }
        Log.d("leon", "startAngles:" + Arrays.toString(startAngles) + " endAngles:" + Arrays.toString(endAngles));

        pathPaint.setStrokeWidth(2);
        pathPaint.setColor(Color.WHITE);
        pathPaint.setStyle(Paint.Style.STROKE);

        lablePaint.setTextSize(30);
        lablePaint.setColor(Color.WHITE);

    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        final float width = getWidth() - getPaddingLeft() - getPaddingRight();
        final float height = getHeight() - getPaddingTop() - getPaddingBottom();
        centerX = width / 2;
        centerY = height / 2;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        final float width = getWidth() - getPaddingLeft() - getPaddingRight();
        final float height = getHeight() - getPaddingTop() - getPaddingBottom();
        canvas.translate(width / 2, height / 2);

//        综合练习
//        练习内容：使用各种 Canvas.drawXXX() 方法画饼图
       /* for (int i = 0; i < angles.length; i++) {
            paint.setColor(colors[i]);
            canvas.drawArc(rect, startAngle, angles[i] - spaceAngle, true, paint);
            startAngle += angles[i];
        }*/
        for (int i = 0; i < angles.length; i++) {
            paint.setColor(colors[i]);
            int middleAngle = getMiddleAngle(startAngles[i], endAngles[i]);
            if (i == selectPosition) {
                canvas.save();
                canvas.translate((float) (translateRadius * Math.cos(Math.toRadians(middleAngle))), (float) (translateRadius * Math.sin(Math.toRadians(middleAngle))));

                canvas.drawArc(rect, startAngles[i] + spaceAngle / 2, (endAngles[i] - startAngles[i] - spaceAngle), true, paint);

                drawLabel(canvas, i, middleAngle);

                canvas.restore();
            } else {
                canvas.drawArc(rect, startAngles[i] + spaceAngle / 2, (endAngles[i] - startAngles[i] - spaceAngle), true, paint);
                drawLabel(canvas, i, middleAngle);
            }


        }
    }

    private void drawLabel(Canvas canvas, int i, int middleAngle) {
        int x = (int) (radius * Math.cos(Math.toRadians(middleAngle)));
        int y = (int) (radius * Math.sin(Math.toRadians(middleAngle)));
        int x1 = (int) ((radius + translateRadius) * Math.cos(Math.toRadians(middleAngle)));
        int y1 = (int) ((radius + translateRadius) * Math.sin(Math.toRadians(middleAngle)));

//        Log.d("leon", "-->onDraw: x:" + x + " y:" + y + " x1:" + x1 + " y1:" + y1);

        leftTopLinePath.reset();
        leftTopLinePath.moveTo(x, y);
        leftTopLinePath.lineTo(x1, y1);
        if (x < 0 && y > 0) {
            leftTopLinePath.lineTo(x1 - 100, y1);
            canvas.drawPath(leftTopLinePath, pathPaint);

            canvas.drawText(labels[i], x1 - 120 - lablePaint.measureText(labels[i]), y1, lablePaint);
        } else if (x >= 0 && y < 0) {
            leftTopLinePath.lineTo(x1 + 100, y1);
            canvas.drawPath(leftTopLinePath, pathPaint);
            canvas.drawText(labels[i], x1 + 120, y1, lablePaint);
        } else if (x >= 0 && y > 0) {
            leftTopLinePath.lineTo(x1 + 100, y1);
            canvas.drawPath(leftTopLinePath, pathPaint);
            canvas.drawText(labels[i], x1 + 120, y1, lablePaint);
        } else {
            leftTopLinePath.lineTo(x1 - 100, y1);
            canvas.drawPath(leftTopLinePath, pathPaint);
            canvas.drawText(labels[i], x1 - 120 - lablePaint.measureText(labels[i]), y1, lablePaint);
        }
    }

    private int getMiddleAngle(int start, int end) {
        int middle = start + (end - start) / 2;
        return (int) limitDegreeInTo360(middle);
    }

    private float limitDegreeInTo360(double inputAngle) {
        float result;
        double tInputAngle = inputAngle - (int) inputAngle; // 取小数
        result = (float) ((int) (inputAngle % 360F) + tInputAngle);
        return result < 0 ? 360f + result : result;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                return true;
//                break;
            case MotionEvent.ACTION_UP:
                boolean isInPie = isInPie(event.getX(), event.getY());
                if (isInPie) {
                    changeSelectPosition(event.getX(), event.getY());
                }
                Log.d("leon", "-->onTouchEvent: x:" + event.getX() + " y :" + event.getY() + " isInPie:" + isInPie);
                return true;
//                break;
        }
        return super.onTouchEvent(event);
    }

    private void changeSelectPosition(float x, float y) {
        double touchAngle = Math.toDegrees(Math.atan2(y - centerY, x - centerX));
        if (touchAngle < 0) {
            touchAngle += 360;
        }
        for (int i = 0; i < startAngles.length; i++) {
            if (containsTouch(touchAngle, startAngles[i], endAngles[i])) {
                selectPosition = i;
                break;
            }
        }
        invalidate();
    }

    private boolean containsTouch(double angle, int startAngle, double endAngle) {
        final float tAngle = limitDegreeInTo360(angle);
        float tStart = limitDegreeInTo360(startAngle);
        float tEnd = limitDegreeInTo360(endAngle);
        Log.d("leon", "-->containsTouch: tAngle:" + tAngle + " tStart:" + tStart + " tEnd:" + tEnd);
        if (tEnd < tStart) {
            if (tAngle > 180) {
                return tAngle >= tStart && (360 - tAngle) <= endAngle - startAngle;
            } else {
                return tAngle <= tEnd && tAngle + 360 >= tStart;
            }
        } else {
            return tAngle >= tStart && tAngle <= tEnd;
        }
//        return false;
    }

    private boolean isInPie(float x, float y) {
        final double touchDistancePow = Math.pow(x - centerX, 2) + Math.pow(y - centerY, 2);
        return touchDistancePow <= Math.pow(radius, 2);
    }
}
